package io.github.source.media.bean;

import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import androidx.annotation.NonNull;


/**
 * @ClassName: AMedia
 * @Description: TODO(AMedia)
 * @author: huangrongcai
 * @date: 2024/6/5
 * @Copyright: 黄嵘才（HuangRc)
 */
public class AMedia implements MediaCall.Factory, MediaProvider {
    /*
     * 提供配置模式，去设置初始化的参数
     * 拦截器
     * 转换器
     * 测试器
     * 广告检查器
     * 播放有效截断器
     * 自动下载
     * 自动跳过错误
     *
     * */

    final List<MediaProvider> interceptors;
    final int callTimeout;
    final int connectTimeout;
    final int readTimeout;
    final int writeTimeout;
    MediaEventListener.Factory eventListenerFactory;
    private static final AtomicReference<AMedia> INSTANCE = new AtomicReference<>();

    // 将构造函数设为私有，防止外部直接实例化
    private AMedia() {
        this(new Builder());
    }

    // 提供一个全局的访问点来获取单例实例
    public static AMedia get() {
        AMedia instance = INSTANCE.get();
        if (instance == null) {
            // 使用 CAS 操作来保证线程安全性
            instance = new AMedia();
            INSTANCE.compareAndSet(null, instance);
        }
        return instance;
    }


    public static MediaProvider with() {
        return MediaProviderImpl.get();
    }

    /**
     * 初始化并加载配置数据。
     */
    public static void init() {

    }

    /**
     * 注册媒体回调监听器。
     *
     * @param callback 回调监听器接口。
     */
    public static void registerListener(MediaCallback callback) {
        MediaCallbackImpl.get().registerListener(callback);
    }

    /**
     * 注销媒体回调监听器。
     *
     * @param callback 回调监听器接口。
     */
    public static void unRegisterListener(MediaCallback callback) {
        MediaCallbackImpl.get().unRegisterListener(callback);
    }

    public List<MediaProvider> interceptors() {
        return interceptors;
    }

    public int callTimeoutMillis() {
        return callTimeout;
    }

    /**
     * Default connect timeout (in milliseconds).
     */
    public int connectTimeoutMillis() {
        return connectTimeout;
    }

    /**
     * Default read timeout (in milliseconds).
     */
    public int readTimeoutMillis() {
        return readTimeout;
    }

    /**
     * Default write timeout (in milliseconds).
     */
    public int writeTimeoutMillis() {
        return writeTimeout;
    }

    AMedia(Builder builder) {
        // 初始化代码
        Logger.i("初始化 MediaProviderImpl");
        this.interceptors = builder.mediaProviders;
        this.eventListenerFactory = builder.eventListenerFactory;
        this.callTimeout = builder.callTimeout;
        this.connectTimeout = builder.connectTimeout;
        this.readTimeout = builder.readTimeout;
        this.writeTimeout = builder.writeTimeout;
    }

    @Override
    public MediaCall newCall(MediaQuery query) {
        return RealMediaCall.newRealCall(this, query);
    }

    public MediaCall newDetailsCall(MediaQuery query) {
        return RealMediaCall.newRealCall(this, query);
    }

    public MediaPlayProvider newPlayCall(MediaQuery query) {
        return MediaPlayProviderImpl.newCall(this, query);
    }

    public MediaCall newQueryCall(MediaQuery query) {
        return RealMediaCall.newRealCall(this, query);
    }

    @Override
    public MediaResult<List<MediaCategory>> getMediaCategory() throws Exception {
        for (MediaProvider provider : interceptors) {
            MediaResult<List<MediaCategory>> result = provider.getMediaCategory();
            if (result != null) {
                return result;
            }
        }
        return MediaResult.error(500).message("");
    }

    @NonNull
    @Override
    public MediaResult<List<MediaBean>> getMediaDetails(MediaQuery opt, MediaBean bean) throws Exception {
        for (MediaProvider provider : interceptors) {
            MediaResult<List<MediaBean>> result = provider.getMediaDetails(opt, bean);
            if (result != null) {
                return result;
            }
        }
        return MediaResult.error(500).message("");
    }

    @Override
    public MediaResult<MediaPlay> getMediaPlayback(MediaQuery query, MediaBean video) throws Exception {
        for (MediaProvider provider : interceptors) {
            MediaResult<MediaPlay> result = provider.getMediaPlayback(query, video);
            if (result != null) {
                return result;
            }
        }
        return MediaResult.error(404).message("没有被处理");
    }

    @Override
    public MediaResult<List<MediaBean>> getMediaList(MediaQuery query) throws Exception {
        for (MediaProvider provider : interceptors) {
            MediaResult<List<MediaBean>> result = provider.getMediaList(query);
            if (result != null) {
                return result;
            }
        }
        return MediaResult.error(500).message("");
    }

    /**
     * 媒体播放器构建器类，用于定制媒体播放器的构建过程
     * 该类主要负责媒体提供者、事件监听器以及超时设置的管理
     */
    public static class Builder {

        /**
         * 构建器构造函数
         * 初始化时，自动添加一个默认的媒体提供者
         */
        public Builder() {
            mediaProviders.add(MediaProvider.get());
        }

        /**
         * 用于存储媒体提供者的列表
         * 媒体提供者负责媒体数据的获取和播放
         */
        final List<MediaProvider> mediaProviders = new ArrayList<MediaProvider>() {
        };

        /**
         * 事件监听器工厂
         * 用于生成媒体播放过程中事件的监听器，初始设置为不记录任何事件
         */
        MediaEventListener.Factory eventListenerFactory = MediaEventListener.factory(MediaEventListener.NONE);

        /**
         * 调用超时时间
         * 控制媒体数据请求的最大等待时间
         */
        int callTimeout;

        /**
         * 连接超时时间
         * 控制建立媒体数据连接的最大等待时间
         */
        int connectTimeout;

        /**
         * 读取超时时间
         * 控制从媒体数据流中读取数据的最大等待时间
         */
        int readTimeout;

        /**
         * 写入超时时间
         * 控制向媒体数据流中写入数据的最大等待时间
         */
        int writeTimeout;
    }
}
